<template>
    <div id="container">
        <div id="viewDiv"></div>
        <el-main style="position:absolute;left:15px;top:15px;width:auto;height:auto;background-color:white;line-height:50px">
            <div style="width:100%" id="sketch"></div>
            <div style="width:100%">
                <el-button @click="重置" type="danger">重置</el-button>
                <el-button @click="执行反向裁剪" type="primary">执行反向裁剪</el-button>
                <el-button @click="拆分多部件要素" type="primary">拆分多部件要素</el-button>
            </div>
        </el-main>
   </div>
</template>
  
<script setup>
/*
  说明:
  两个定义---输入要素:被裁剪的要素集合;裁剪要素:作为剪刀的要素;输出要素:执行裁剪后返回的要素集合
  1:创建两个图形图层对象graphicsLayer1和graphicsLayer2分别用于存储输入要素和裁剪要素
  2:创建一个sketch对象用于绘制输入要素(关联graphicsLayer1)
  3:创建skeketchViewModel对象用于绘制裁剪要素(面要素)(关联graphicsLayer2)
  4:创建一个数组变量graphics作为一个暂时的容器存储裁剪返回的图形集合
*/
import * as 天地图 from '../天地图'
import {onMounted} from 'vue'
import Map from '@arcgis/core/Map'
import MapView from '@arcgis/core/views/MapView'
import * as geometryEngine from "@arcgis/core/geometry/geometryEngine.js"
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer'
import Sketch from '@arcgis/core/widgets/Sketch'
import SketchViewModel from '@arcgis/core/widgets/Sketch/SketchViewModel'
var map,view,graphicsLayer1,graphicsLayer2,sketch,sketchViewModel
var graphics=[]
const 执行反向裁剪=()=>{//点击按钮开始绘制裁剪图形
  sketchViewModel.create("polygon",{mode:"freehand"})
}
const 重置=()=>{//清空两个图形图层的所有图形和相关变量
  graphicsLayer1.graphics.removeAll()
  graphicsLayer2.graphics.removeAll()
  graphics=[]
}
const 拆分多部件要素=()=>{//点击"拆分多部件要素"按钮事件处理函数
  for(let graphic of graphicsLayer1.graphics.items){//遍历graphicsLayer1图层中绘制的输入图形
    if(graphic.geometry.type==="polyline"){//如果为线要素
      if(graphic.geometry.paths.length>1){//判断是否为多部件要素
        for(let path of graphic.geometry.paths){//遍历paths
          var graphic_=graphic.clone()//复制这个图形
          graphic_.geometry.paths=[path]//将图形的多个paths拆分为单个path
          graphics.push(graphic_)//向graphics添加这个图形
        }
      }else{//如果并非多部件要素,直接向graphics添加这个图形
        graphics.push(graphic)
      }
    }else if(graphic.geometry.type==="polygon"){
      if(graphic.geometry.type==="polygon"){
        if(graphic.geometry.rings.length>1){
          for(let ring of graphic.geometry.rings){
            var graphic_=graphic.clone()
            graphic_.geometry.rings=[ring]
            graphics.push(graphic_)
          }
        }else{
          graphics.push(graphic)
        }
      }
    }
  }
  graphicsLayer1.removeAll()//清空现有图形
  graphicsLayer1.addMany(graphics)//向graphicsLayer1添加graphics变量中的图形集合
  graphics=[]
}
onMounted(()=>{
  graphicsLayer1=new GraphicsLayer()
  graphicsLayer2=new GraphicsLayer()
    map=new Map({
        basemap:{
          baseLayers:天地图.天地图矢量
        },
        layers:[graphicsLayer1,graphicsLayer2]
    })
    view=new MapView({
      map:map,
      container:"viewDiv",
      center:[120.4,36.1],
      zoom:15,
      constraints:{
          rotationEnabled:false,
          maxScale:2000
      }
  })
  view.ui.remove(["zoom","attribution"])
  sketch=new Sketch({//创建绘图工具小部件,使用该小部件绘制原始图形的集合
    view:view,
    container:"sketch",
    layer:graphicsLayer1//绑定存储绘制图形的图层
  })
  sketchViewModel=new SketchViewModel({
    view:view,
    layer:graphicsLayer2//绑定存储裁剪图形的图层
  })
  sketchViewModel.on("create",(event)=>{//!!!创建裁剪图形完成事件处理函数
    if(event.state==="complete"){
      //👇第一参数是输入要素的几何的集合,第二参数是裁剪要素的几何
      //如果第一参数是数组则结果返回数组,否则将返回几何对象
      graphics=geometryEngine.difference(graphicsLayer1.graphics.items.map((item)=>{
        if(item.geometry.type!=="point"){//剔除点要素
          return item.geometry
        }
      }),event.graphic.geometry).map((geometry)=>{
        var graphic={
          geometry:geometry,
          symbol:sketchViewModel.polygonSymbol
        }
        return graphic
      })//将执行计算差异后返回的图形存放到graphics中
      graphicsLayer1.graphics.removeAll()
      graphicsLayer2.graphics.removeAll()
      graphicsLayer1.graphics.addMany(graphics)//将graphics中的图形集合添加到graphicsLayer1中
      graphics=[]
    }
  })
})
</script>

<style scoped>
  #container,#viewDiv{
  width:100%; height:100%; padding:0;margin:0;
  }
  span{
    vertical-align: middle;
    white-space: pre-line;
  }
</style>
  